<template>
  <el-dialog v-model="state.mapVisible" title="选择地址" width="1000" @close="closeMap">
    <baidu-map
      v-if="state.baidu.ak && state.mapReady"
      v-loading="state.baidu.loading"
      :center="state.baidu.center"
      :zoom="state.baidu.zoom"
      @ready="handler"
      @click="getLocationPoint"
      @moving="syncCenterAndZoom"
      @moveend="syncCenterAndZoom"
      @zoomend="syncCenterAndZoom"
      :ak="state.baidu.ak"
      class="map"
      v="3.0"
      type="API"
      :scroll-wheel-zoom="true"
    >
      <bm-navigation anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
      <bm-geolocation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" :showAddressBar="false" :autoLocation="false"></bm-geolocation>

      <bm-marker
        :position="{
          lng: state.baidu.location.lng,
          lat: state.baidu.location.lat
        }"
        :dragging="true"
        @click="infoWindowOpen"
      >
        <bm-info-window :show="state.mapInfoWindow" @close="infoWindowClose" @open="infoWindowOpen">
          <div class="info-window-content">
            <div>{{ "地址" }}</div>
            <div style="margin-top: 10px">{{ state.baidu.addressKeyword }}</div>
          </div>
        </bm-info-window>
      </bm-marker>
      <bm-local-search
        :panel="state.isShowPanel"
        :keyword="state.keyword"
        :auto-viewport="true"
        :location="state.location"
        :forceLocal="false"
        @searchcomplete="searchcomplete"
        @infohtmlset="infohtmlset"
        class="hideScrollbar localSearch"
      ></bm-local-search>
    </baidu-map>
    <div class="mt20" style="position: static">
      <div>
        <el-form label-width="auto">
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="关键词：">
                <el-input v-model="state.keyword" placeholder="请输入关键词搜索" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <div>
        <el-form label-width="auto">
          <el-row :gutter="20">
            <el-col :span="5">
              <el-form-item label="经度：">
                <el-input v-model="state.baidu.location.lat" placeholder="经度" />
              </el-form-item>
            </el-col>
            <el-col :span="5">
              <el-form-item label="纬度：">
                <el-input v-model="state.baidu.location.lng" placeholder="纬度" />
              </el-form-item>
            </el-col>
            <el-col :span="14">
              <el-form-item label="当前地址：">
                <el-input v-model="state.baidu.addressKeyword" placeholder="当前地址" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeMap">取消</el-button>
        <el-button type="primary" @click="confirmMap">确认地址</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup name="BaiduMap">
import { BaiduMap, BmNavigation, BmGeolocation, BmMarker, BmLocalSearch, BmInfoWindow } from "vue-baidu-map-3x";
import { onMounted, nextTick, reactive } from "vue";
const emit = defineEmits(["closeMap", "confirmMap"]);
const props = defineProps({
  ak: {
    type: String,
    default: "",
    required: true
  },
  mapVisible: {
    type: Boolean,
    default: false
  }
});

const state = reactive({
  mapVisible: false,
  mapReady: false,
  mapInfoWindow: false,
  baidu: {
    loading: true,
    map: {},
    BMap: {},
    currentData: {},
    zoom: 15,
    center: {
      lng: 0,
      lat: 0
    },
    location: {
      lat: 0, // 经度
      lng: 0 // 纬度
    },
    addressKeyword: "",
    ak: props.ak
  },
  keyword: "",
  location: "",
  isShowPanel: false
});
const handler = ({ BMap, map }) => {
  state.baidu.BMap = BMap;
  state.baidu.map = map;
  getCurrentLocation();
};

const infoWindowClose = () => {
  state.mapInfoWindow = false;
};
const infoWindowOpen = () => {
  state.mapInfoWindow = true;
};
// 获取当前位置
const getCurrentLocation = () => {
  state.baidu.loading = true;
  // 获取用户当前位置
  const { map, BMap } = state.baidu;
  const geolocation = new BMap.Geolocation();

  geolocation.getCurrentPosition(
  // localhost下使用百度地图可能会获取不到当前定位位置（event会是null)
    event => {
      const point = new state.baidu.BMap.Point(event.point.lng, event.point.lat);
      map.centerAndZoom(point, state.baidu.zoom);
      nextTick(() => {
        setTimeout(() => {
          map.checkResize();
          state.baidu.center.lng = point.lng;
          state.baidu.center.lat = point.lat;
          state.baidu.location = {
            lat: point.lat,
            lng: point.lng
          };

          state.baidu.addressKeyword =
            event.address.province +
            event.address.city +
            event.address.district +
            event.address.street +
            event.address.street_number;
          state.baidu.currentData = {
            address: state.baidu.addressKeyword,
            point: event.point,
            addressComponents: {
              city: event.address.city,
              district: event.address.district
            }
          };
          state.baidu.loading = false;
        }, 2000);
      });
    },
    {
      enableHighAccuracy: true
    }
  );
};

const syncCenterAndZoom = e => {
  nextTick(() => {
    state.baidu.center.lng = state.baidu.location.lng;
    state.baidu.center.lat = state.baidu.location.lat;
  });
};

const closeMap = () => {
  state.mapVisible = false;
  state.baidu.currentData = {};
  state.baidu.center = { lng: 0, lat: 0 };
  emit("closeMap");
};

const confirmMap = () => {
  let addressData = {
    address: state.baidu.addressKeyword,
    lat: state.baidu.location.lat,
    lng: state.baidu.location.lng
  };
  state.mapVisible = false;
  emit("confirmMap", addressData);
};

const getLocationPoint = e => {
  /* 创建地址解析器的实例 */
  let geoCoder = new BMap.Geocoder();
  /* 利用坐标获取地址的详细信息 */
  geoCoder.getLocation(e.point, res => {
    state.baidu.currentData = res;
    state.baidu.location = e.point;
    state.baidu.addressKeyword = res.address;
  });
  nextTick(() => {
    state.baidu.center.lng = e.point.lng;
    state.baidu.center.lat = e.point.lat;
  });
};

const searchcomplete = () => {
  state.isShowPanel = true;
};

const infohtmlset = e => {
  let param = {
    point: ""
  };
  param.point = e.point;
  getLocationPoint(param);
  state.isShowPanel = false;
  nextTick(() => {
    state.baidu.center.lng = state.baidu.location.lng;
    state.baidu.center.lat = state.baidu.location.lat;
  });
};

onMounted(() => {
  nextTick(() => {
    state.mapReady = true;
    state.mapVisible = props.mapVisible;
  });
});
</script>

<style lang="scss" scoped>
.map {
  width: 100%;
  height: 400px;
  position: relative;
  .info-window-content {
    text-align: center; /* 文本居中 */
    white-space: pre-line; /* 保留换行符并自动换行 */
    word-break: break-all; /* 长单词或URL强制换行 */
    max-width: 200px; /* 可选：限制宽度以强制换行 */
  }
  .localSearch {
    max-height: 120px;
    overflow: auto;
    position: absolute;
    bottom: 0;
    width: 100%;
  }
}
:deep(.BMap_cpyCtrl) {
  display: none;
}
:deep(.anchorBL) {
  display: none !important;
}
</style>
